﻿// --------------------------------
// <copyright file="FacebookCoreLib.cs" company="Samaj Shekhar">
//     Copyright (c) 2010-2011 Samaj Shekhar
// </copyright>
// <author>Samaj Shekhar (samaj.shekhar@hotmail.com)</author>
// <license>Released under the terms of the Microsoft Public License (Ms-PL)</license>
// <website>http://thesharepage.codeplex.com</website>
// ---------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using SharePage.CoreLib.Utils.ExtentionMethods;
using SharePage.CoreLib;
using System.Web.Security;

//NOTE: I have not implemented all the features of facebook in my NIIT project, 
//      this namespace may contain implementations or features which are not fully functional
//      or are abstract or just not used in project.
//      However this namespace will act as a base for future implementations and expansions i may do.
//      For further details please contact me.
namespace SharePage.CoreLib.Facebook
{
    //Contains facebok permissions class
    #region FacebookPermissionsClass
    /// <summary>
    /// <para>Encapsulates the methods and enumerations to manage and use Facebook permissions</para>
    /// <para>For info about Permissions Please visit : http://developers.facebook.com/docs/authentication/permissions </para>
    /// </summary>
    /// <remarks>
    /// Copyright: Copyright (c) 2010-2011 Samaj Shekhar
    /// Last Update: 22-Dec-2010|04:52am
    /// </remarks>
    public class FacebookPermissions
    {
        /// <summary>
        /// <para>Represents a enumeration of Extented permissions that can be requested during Authorization request</para>
        /// <para>For info about Extented Permissions Please visit : http://developers.facebook.com/docs/authentication/permissions </para>
        /// </summary>
        /// <remarks>
        /// NOTE: Integer values for ExtendedPermissions starts with differen values for different Permission types
        ///     101: Publishing Permissions
        ///     201: User Data Permissions
        ///     301: Friends Data Permissions
        ///     401: Page Permissions
        /// </remarks>
        public enum ExtendedPermissions
        {
            /// <summary>
            /// <para>Enables your application to post content, comments, and likes to a user's stream and to </para>
            /// <para>the streams of the user's friends. With this permission, you can publish content to a user's</para>
            /// <para>feed at any time, without requiring offline_access.</para>
            /// </summary>
            publish_stream = 101,

            /// <summary>
            /// Enables your application to create and modify events on the user's behalf.
            /// </summary>
            create_event,

            /// <summary>
            /// Enables your application to RSVP to events on the user's behalf.
            /// </summary>
            rsvp_event,

            /// <summary>
            /// <para>Enables your application to send messages to the user and respond to messages from the</para>
            /// <para>user via text message.</para>
            /// </summary>
            sms,

            /// <summary>
            /// <para>Enables your application to perform authorized requests on behalf of the user at any time.</para>
            /// <para>By default, most access tokens expire after a short time period to ensure applications only </para>
            /// <para>make requests on behalf of the user when the are actively using the application. This </para>
            /// <para>permission makes the access token returned by our OAuth endpoint long-lived.</para>
            /// </summary>
            offline_access,

            /// <summary>
            /// Enables your application to perform checkins on behalf of the user.
            /// </summary>
            publish_checkins,

            /// <summary>
            /// Provides access to the "About Me" section of the profile in the about property.
            /// </summary>
            user_about_me = 201,

            /// <summary>
            /// Provides access to the user's list of activities as the activities connection.
            /// </summary>
            user_activities,

            /// <summary>
            /// Provides access to the birthday with year as the birthday_date property.
            /// </summary>
            user_birthday,

            /// <summary>
            /// Provides access to education history as the education property.
            /// </summary>
            user_education_history,

            /// <summary>
            /// Provides access to the list of events the user is attending as the events connection.
            /// </summary>
            user_events,

            /// <summary>
            /// Provides access to the list of groups the user is a member of as the groups connection.
            /// </summary>
            user_groups,

            /// <summary>
            /// Provides access to the user's hometown in the hometown property.
            /// </summary>
            user_hometown,

            /// <summary>
            /// Provides access to the user's list of interests as the interests connection.
            /// </summary>
            user_interests,

            /// <summary>
            /// Provides access to the list of all of the pages the user has liked as the likes connection.
            /// </summary>
            user_likes,

            /// <summary>
            /// Provides access to the user's current location as the location property.
            /// </summary>
            user_location,

            /// <summary>
            /// Provides access to the user's notes as the notes connection.
            /// </summary>
            user_notes,

            /// <summary>
            /// Provides access to the user's online/offline presence.
            /// </summary>
            user_online_presence,

            /// <summary>
            /// Provides access to the photos the user has been tagged in as the photos connection.
            /// </summary>
            user_photo_video_tags,

            /// <summary>
            /// Provides access to the photos the user has uploaded.
            /// </summary>
            user_photos,

            /// <summary>
            /// Provides access to the user's family and personal relationships and relationship status.
            /// </summary>
            user_relationships,

            /// <summary>
            /// Provides access to the user's relationship preferences.
            /// </summary>
            user_relationship_details,

            /// <summary>
            /// Provides access to the user's religious and political affiliations.
            /// </summary>
            user_religion_politics,

            /// <summary>
            /// Provides access to the user's most recent status message.
            /// </summary>
            user_status,

            /// <summary>
            /// Provides access to the videos the user has uploaded.
            /// </summary>
            user_videos,

            /// <summary>
            /// Provides access to the user's web site URL.
            /// </summary>
            user_website,

            /// <summary>
            /// Provides access to work history as the work property.
            /// </summary>
            user_work_history,

            /// <summary>
            /// Provides access to the user's primary email address in the email property. Do not spam users.
            /// </summary>
            email,

            /// <summary>
            /// Provides read access to any friend lists the user created.
            /// </summary>
            read_friendlists,

            /// <summary>
            /// Provides read access to the Insights data for pages, applications, and domains the user owns.
            /// </summary>
            read_insights,

            /// <summary>
            /// Provides the ability to read from a user's Facebook Inbox.
            /// </summary>
            read_mailbox,

            /// <summary>
            /// Provides read access to the user's friend requests
            /// </summary>
            read_requests,

            /// <summary>
            /// Provides access to all the posts in the user's News Feed and enables your application to perform searches against the user's News Feed
            /// </summary>
            read_stream,

            /// <summary>
            /// Provides applications that integrate with Facebook Chat the ability to log in users.
            /// </summary>
            xmpp_login,

            /// <summary>
            /// Provides the ability to manage ads and call the Facebook Ads API on behalf of a user.
            /// </summary>
            ads_management,

            /// <summary>
            /// Provides read access to the authorized user's check-ins or a friend's check-ins that the user can see.
            /// </summary>
            user_checkins,

            /// <summary>
            /// Provides access to the "About Me" section of the profile in the about property
            /// </summary>
            friends_about_me = 301,

            /// <summary>
            /// Provides access to the user's list of activities as the activities connection
            /// </summary>
            friends_activities,

            /// <summary>
            /// Provides access to the birthday with year as the birthday_date property
            /// </summary>
            friends_birthday,

            /// <summary>
            /// Provides access to education history as the education property
            /// </summary>
            friends_education_history,

            /// <summary>
            /// Provides access to the list of events the user is attending as the events connection
            /// </summary>
            friends_events,

            /// <summary>
            /// Provides access to the list of groups the user is a member of as the groups connection
            /// </summary>
            friends_groups,

            /// <summary>
            /// Provides access to the user's hometown in the hometown property
            /// </summary>
            friends_hometown,

            /// <summary>
            /// Provides access to the user's list of interests as the interests connection
            /// </summary>
            friends_interests,

            /// <summary>
            /// Provides access to the list of all of the pages the user has liked as the likes connection
            /// </summary>
            friends_likes,

            /// <summary>
            /// Provides access to the user's current location as the location property
            /// </summary>
            friends_location,

            /// <summary>
            /// Provides access to the user's notes as the notes connection
            /// </summary>
            friends_notes,

            /// <summary>
            /// Provides access to the user's online/offline presence
            /// </summary>
            friends_online_presence,

            /// <summary>
            /// Provides access to the photos the user has been tagged in as the photos connection
            /// </summary>
            friends_photo_video_tags,

            /// <summary>
            /// Provides access to the photos the user has uploaded
            /// </summary>
            friends_photos,

            /// <summary>
            /// Provides access to the user's family and personal relationships and relationship status
            /// </summary>
            friends_relationships,

            /// <summary>
            /// Provides access to the user's relationship preferences
            /// </summary>
            friends_relationship_details,

            /// <summary>
            /// Provides access to the user's religious and political affiliations
            /// </summary>
            friends_religion_politics,

            /// <summary>
            /// Provides access to the user's most recent status message
            /// </summary>
            friends_status,

            /// <summary>
            /// Provides access to the videos the user has uploaded
            /// </summary>
            friends_videos,

            /// <summary>
            /// Provides access to the user's web site URL
            /// </summary>
            friends_website,

            /// <summary>
            /// Provides access to work history as the work property
            /// </summary>
            friends_work_history,

            /// <summary>
            /// Provides read access to the authorized user's check-ins or a friend's check-ins that the user can see.
            /// </summary>
            friends_checkins,

            /// <summary>
            /// Enables your application to retrieve access_tokens for pages the user administrates
            /// </summary>
            manage_pages = 401,
        }

        /// <summary>
        /// Represents the enumeration of Permission Types
        /// </summary>
        public enum PermissionType
        {
            /// <summary>
            /// Permissions for publishing to user stream
            /// </summary>
            Publishing_Permissions = 1,

            /// <summary>
            /// Permissions for getting user's non public information
            /// </summary>
            User_Data_Permissions,

            /// <summary>
            /// Permissions for getting user's friend's non public information
            /// </summary>
            Friends_Data_Permissions,

            /// <summary>
            /// Permission for managing user's pages
            /// </summary>
            Page_Permissions,
        }

        /// <summary>
        /// <para>Dictonary to hold permissions in form of key, value pair where</para>
        /// <para>-key is the permission of <code>ExtendedPermission</code> type</para>
        /// <para>-value is the permission type of <code>PermissionType</code> type</para>
        /// </summary>
        private Dictionary<ExtendedPermissions, PermissionType> _PermissionsDictonary = new Dictionary<ExtendedPermissions, PermissionType>();

        /// <summary>
        /// <para>Gets the Dictonary which holds permissions in form of key, value pair where (Readonly Property)</para>
        /// <para>-key is the permission of <code>ExtendedPermission</code> type</para>
        /// <para>-value is the permission type of <code>PermissionType</code> type</para>
        /// </summary>
        public IDictionary<ExtendedPermissions, PermissionType> Permissions
        {
            get
            {
                return _PermissionsDictonary;
            }
        }

        /// <summary>
        /// Adds a given permission
        /// </summary>
        /// <param name="permission">An <code>ExtendedPermissions</code></param>
        public void Add(ExtendedPermissions permission)
        {
            PermissionType pt;
            if ((int)permission > 400)
            {
                pt = PermissionType.Page_Permissions;
            }
            else
            {
                if ((int)permission > 300)
                {
                    pt = PermissionType.Friends_Data_Permissions;
                }
                else
                {
                    if ((int)permission > 200)
                    {
                        pt = PermissionType.User_Data_Permissions;
                    }
                    else
                    {
                        pt = PermissionType.Publishing_Permissions;
                    }
                }
            }
            if (!_PermissionsDictonary.ContainsKey(permission))
            {
                _PermissionsDictonary.Add(permission, pt);
            }
        }

        /// <summary>
        /// Adds a range of permissions from given array of <code>ExtendedPermissions</code>
        /// </summary>
        /// <param name="permissions">An array of <code>ExtendedPermissions</code></param>
        public void AddRange(ExtendedPermissions[] permissions)
        {
            foreach (var permission in permissions)
            {
                PermissionType pt;
                if ((int)permission > 400)
                {
                    pt = PermissionType.Page_Permissions;
                }
                else
                {
                    if ((int)permission > 300)
                    {
                        pt = PermissionType.Friends_Data_Permissions;
                    }
                    else
                    {
                        if ((int)permission > 200)
                        {
                            pt = PermissionType.User_Data_Permissions;
                        }
                        else
                        {
                            pt = PermissionType.Publishing_Permissions;
                        }
                    }
                }
                if (!_PermissionsDictonary.ContainsKey(permission))
                {
                    _PermissionsDictonary.Add(permission, pt);
                }
            }
        }

        /// <summary>
        /// Checks wheather a given <code>ExtendedPermissions</code> has been added
        /// </summary>
        /// <param name="permission">An <code>ExtendedPermissions</code></param>
        /// <returns>Returns True if permission exists, otherwise False</returns>
        public bool Contains(ExtendedPermissions permission)
        {
            return _PermissionsDictonary.ContainsKey(permission);
        }

        /// <summary>
        /// Combines all the permissions and returns its string representation in a csv format
        /// </summary>
        /// <returns>Returns a csv representation of all permissions</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            if (_PermissionsDictonary.Count > 0)
            {
                foreach (var item in _PermissionsDictonary.Keys)
                {
                    sb.Append(FacebookPermissions.ToString(item));
                    sb.Append(',');
                }
                //trimming ensures that trailing commas are removed before returning the csv string
                return sb.ToString().TrimEnd(',');
            }
            return string.Empty;
        }

        /// <summary>
        /// A method to convert the given Extended Permission name to string (Static Method)
        /// </summary>
        /// <param name="permission">Any one of the permissions of Extended Permission Enumeration</param>
        /// <returns>Returns a string representation of the the given Extended Permisssion</returns>
        public static string ToString(ExtendedPermissions permission)
        {
            return Enum.GetName(typeof(ExtendedPermissions), permission);
        }
    }

#endregion FacebookPermissionsClass

    //TODO:ADD DOCUMENTATION BELOW

    public class FacebookUrls
    { 
        public static string GetSignUpUrl(FacebookPermissions permissions,string App_ID,string redirecturi, string display="page")
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.Append("graph.facebook.com/oauth/authorize");
            sb.AppendFormat("?client_id={0}&redirect_uri={1}&scope={2}&display={3}", App_ID, System.Web.HttpUtility.UrlEncode(redirecturi), permissions.ToString(), display);
            return sb.ToString();
        }

        public static string GetAccessTokenUrl(string AppID, string RedirectUri, string ClientSecret, string Code)
        { 
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.Append("graph.facebook.com/oauth/access_token");
            sb.AppendFormat("?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}", AppID, System.Web.HttpUtility.UrlEncode(RedirectUri), ClientSecret, Code);
            return sb.ToString();
        }
        public static string GetFacebook_NewUserUrl(string AccessToken)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.Append("graph.facebook.com/me");
            sb.AppendFormat("?access_token={0}",AccessToken);
            return sb.ToString();
        }

        public static string GetFacebook_PictureUrl(Int64 UserID)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.AppendFormat("graph.facebook.com/{0}/picture",UserID.ToString());
            return sb.ToString();
        }


        public static string GetFacebook_PictureUrl(string UserID)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.AppendFormat("graph.facebook.com/{0}/picture", UserID.ToString());
            return sb.ToString();
        }

        public static string GetFacebook_BigPictureUrl(Int64 UserID, string AccessToken)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.AppendFormat("graph.facebook.com/{0}/picture", UserID.ToString());
            sb.AppendFormat("?&type=large&access_token={0}", AccessToken);
            return sb.ToString();
        }

        public static string GetFacebook_BigPictureUrl(Int64 UserID)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.AppendFormat("graph.facebook.com/{0}/picture", UserID.ToString());
            sb.AppendFormat("?&type=large");
            return sb.ToString();
        }
        
        public static string GetFacebook_FriendsUrl(Int64 UserID, string AccessToken)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.AppendFormat("graph.facebook.com/{0}/friends", UserID.ToString());
            sb.AppendFormat("?access_token={0}",AccessToken);
            return sb.ToString();
        }


        public static string GetFacebook_FeedUrl(Int64 UserID, string AccessToken)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("https://");
            sb.AppendFormat("graph.facebook.com/{0}/feed", UserID.ToString());
            sb.AppendFormat("?limit=5&access_token={0}", AccessToken);
            return sb.ToString();
        }
    }

}